package com.hhc.service.impl;

import com.hhc.dto.AverageScoreDTO;
import com.hhc.dto.GradeDTO;
import com.hhc.dto.GradeListQuery;
import com.hhc.entity.GradeRecordDO;
import com.hhc.repository.GradeRecordRepository;
import com.hhc.repository.StudentCourseSelectionRepository;
import com.hhc.repository.TeacherCourseAssignmentRepository;
import com.hhc.service.GradeService;
import com.hhc.utils.RestResult;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

/**
 * <p>
 *   成绩管理业务逻辑实现
 * </p>
 * @author pc
 */
@Slf4j
@Service
@Validated
public class GradeServiceImpl implements GradeService {

    @Autowired
    private GradeRecordRepository gradeRecordRepository;

    @Autowired
    private TeacherCourseAssignmentRepository teacherCourseAssignmentRepository;

    @Autowired
    private StudentCourseSelectionRepository studentCourseSelectionRepository;

    @Override
    @Transactional
    public RestResult<GradeRecordDO> recordStudentGrade(GradeDTO gradeDTO, Long teacherId) {
        // 校验学生是否已选该课程
        if (!studentCourseSelectionRepository.existsByStudentIdAndCourseId(gradeDTO.getStudentId(), gradeDTO.getCourseId())) {
            return RestResult.error("000001", "学生未选此课程");
        }

        // 校验教师是否有权限录入该课程的成绩
        if (!teacherCourseAssignmentRepository.existsByTeacherIdAndCourseId(teacherId, gradeDTO.getCourseId())) {
            return RestResult.error("000001", "无权录入该课程成绩");
        }

        // 保存成绩记录到数据库
        GradeRecordDO gradeRecordDO = new GradeRecordDO();
        gradeRecordDO.setStudentId(gradeDTO.getStudentId());
        gradeRecordDO.setCourseId(gradeDTO.getCourseId());
        gradeRecordDO.setScore(gradeDTO.getScore());
        gradeRecordDO.setExamDate(gradeDTO.getExamDate());
        gradeRecordDO.setRemark(gradeDTO.getRemark());
        gradeRecordDO.setCreateBy(String.valueOf(teacherId));
        gradeRecordDO.setUpdateBy(String.valueOf(teacherId));

        GradeRecordDO savedGradeRecord = gradeRecordRepository.save(gradeRecordDO);

        return RestResult.ok(savedGradeRecord);
    }

    @Override
    public RestResult<List<GradeRecordDO>> getStudentGradeList(GradeListQuery gradeListQuery) {
        Long studentId = gradeListQuery.getStudentId();
        Long courseId = gradeListQuery.getCourseId();
        Integer pageIndex = gradeListQuery.getPageIndex();
        Integer pageSize = gradeListQuery.getPageSize();

        List<GradeRecordDO> gradeRecords;

        if (studentId != null && courseId != null) {
            gradeRecords = gradeRecordRepository.findByStudentIdAndCourseId(studentId, courseId);
        } else if (studentId != null) {
            // 使用 findByStudentId 方法替代 findAllByStudentId
            gradeRecords = gradeRecordRepository.findByStudentId(studentId);
        } else if (courseId != null) {
            gradeRecords = gradeRecordRepository.findByCourseId(courseId);
        } else {
            gradeRecords = gradeRecordRepository.findAll();
        }

        return RestResult.ok(gradeRecords.subList((pageIndex - 1) * pageSize, Math.min(pageIndex * pageSize, gradeRecords.size())));
    }

    @Override
    public RestResult<AverageScoreDTO> getCourseAverageScore(Long courseId) {
        List<GradeRecordDO> gradeRecords = gradeRecordRepository.findByCourseId(courseId);

        if (gradeRecords.isEmpty()) {
            return RestResult.error("000001", "成绩记录不存在");
        }

        BigDecimal totalScore = gradeRecords.stream()
                .map(GradeRecordDO::getScore)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal averageScore = totalScore.divide(BigDecimal.valueOf(gradeRecords.size()), BigDecimal.ROUND_HALF_UP);

        AverageScoreDTO averageScoreDTO = new AverageScoreDTO();
        averageScoreDTO.setCourseId(courseId);
        averageScoreDTO.setAverageScore(averageScore);

        return RestResult.ok(averageScoreDTO);
    }

    @Override
    public RestResult<GradeRecordDO> getStudentGradeDetail(Long gradeRecordId) {
        Optional<GradeRecordDO> gradeRecordOptional = gradeRecordRepository.findById(gradeRecordId);

        if (!gradeRecordOptional.isPresent()) {
            return RestResult.error("000001", "成绩记录不存在");
        }

        GradeRecordDO gradeRecordDO = gradeRecordOptional.get();

        return RestResult.ok(gradeRecordDO);
    }
}
